package com.gitee.melin.bee.core.jdbc.parser;

import com.gitee.melin.bee.core.jdbc.enums.DataSourceType;

public class MysqlURLParser extends AbstractURLParser {

    private static final String DEFAULT_HOST = "localhost";

    private static final int DEFAULT_PORT = 3306;

    protected DataSourceType dsType() {
        return DataSourceType.MYSQL;
    }

    @Override
    protected URLLocation fetchDatabaseHostsIndexRange(String url) {
        int hostLabelStartIndex = url.indexOf("//") + 2;
        int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex);
        if (hostLabelEndIndex == -1) {
            int queryStringStartIndex = url.indexOf("?", hostLabelStartIndex);
            if (queryStringStartIndex == -1) {
                hostLabelEndIndex = url.length();
            } else {
                hostLabelEndIndex = queryStringStartIndex;
            }
        }
        return new URLLocation(hostLabelStartIndex, hostLabelEndIndex);
    }

    protected String fetchDatabaseNameFromURL(String url, int startSize) {
        URLLocation hostsLocation = fetchDatabaseNameIndexRange(url, startSize);
        if (hostsLocation == null) {
            return "";
        }
        return url.substring(hostsLocation.startIndex(), hostsLocation.endIndex());
    }

    protected URLLocation fetchDatabaseNameIndexRange(String url, int startSize) {
        int databaseStartTag = url.indexOf("/", startSize);
        if (databaseStartTag == -1) {
            return null;
        }
        int databaseEndTag = url.indexOf("?", databaseStartTag);
        if (databaseEndTag == -1) {
            databaseEndTag = url.length();
        }
        return new URLLocation(databaseStartTag + 1, databaseEndTag);
    }

    @Override
    protected URLLocation fetchDatabaseNameIndexRange(String url) {
        int databaseStartTag = url.lastIndexOf("/");
        int databaseEndTag = url.indexOf("?", databaseStartTag);
        if (databaseEndTag == -1) {
            databaseEndTag = url.length();
        }
        return new URLLocation(databaseStartTag + 1, databaseEndTag);
    }

    @Override
    public JdbcURLInfo parse(String url) {
        URLLocation location = fetchDatabaseHostsIndexRange(url);
        String hosts = url.substring(location.startIndex(), location.endIndex());
        if (hosts.isEmpty()) {
            hosts = DEFAULT_HOST;
        }
        String[] hostSegment = hosts.split(",");
        if (hostSegment.length > 1) {
            StringBuilder sb = new StringBuilder();
            for (String host : hostSegment) {
                if (host.split(":").length == 1) {
                    sb.append(host + ":" + DEFAULT_PORT + ",");
                } else {
                    sb.append(host + ",");
                }
            }
            if (',' == sb.charAt(sb.length() - 1)) {
                sb.deleteCharAt(sb.length() - 1);
            }
            return new JdbcURLInfo.Builder(sb.toString())
                    .dsType(dsType())
                    .dbInstance(fetchDatabaseNameFromURL(url))
                    .build();
        } else {
            String[] hostAndPort = hostSegment[0].split(":");
            if (hostAndPort.length != 1) {
                return new JdbcURLInfo.Builder(hostAndPort[0] + ":" + Integer.valueOf(hostAndPort[1]))
                        .dsType(dsType())
                        .dbInstance(fetchDatabaseNameFromURL(url, location.endIndex()))
                        .build();
            } else {

                return new JdbcURLInfo.Builder(hostAndPort[0] + ":" + DEFAULT_PORT)
                        .dsType(dsType())
                        .dbInstance(fetchDatabaseNameFromURL(url, location.endIndex()))
                        .build();
            }
        }
    }
}
